from functools import wraps
from django.apps import apps
from rest_framework.decorators import action as drf_action

from .permissions import register_custom_permissions, generate_action_permission

def action_permission(methods=None, detail=False, permission_description=None, **kwargs):
    """
    扩展 DRF 的 @action 装饰器，自动创建相应的权限
    用法：
    @action_permission(methods=['POST'], detail=True, permission_description="Can reset user password")
    def reset_password(self, request, pk=None):
        ...
    """
    def decorator(func):
        # 获取原始的 action 装饰器
        action_decorator = drf_action(methods=methods, detail=detail, **kwargs)
        
        # 获取视图集对应的模型
        def get_model():
            try:
                # 从函数定义的类中获取模型
                view_class = func.__qualname__.split('.')[0]
                model = None
                
                # 遍历所有已安装的应用查找模型
                for app_config in apps.get_app_configs():
                    for model_class in app_config.get_models():
                        view_set_class = f"{model_class.__name__}ViewSet"
                        if view_set_class == view_class:
                            model = model_class
                            break
                    if model:
                        break
                
                return model
            except Exception:
                # 忽略任何错误
                return None
        
        try:
            # 在装饰器应用时注册权限
            model = get_model()
            if model:
                model_name = model._meta.model_name
                action_name = func.__name__
                codename, name = generate_action_permission(
                    model_name,
                    action_name,
                    permission_description
                )
                register_custom_permissions(model, [(codename, name)])
                
                # 保存权限信息供后续使用
                func.permission_codename = f"{model._meta.app_label}.{codename}"
        except Exception:
            # 忽略权限注册过程中的任何错误
            pass
        
        @wraps(func)
        def wrapper(self, *args, **kwargs):
            # 调用原始函数
            return func(self, *args, **kwargs)
        
        # 应用原始的 action 装饰器
        wrapped = action_decorator(wrapper)
        
        # 复制权限信息到包装后的函数
        if hasattr(func, 'permission_codename'):
            wrapped.permission_codename = func.permission_codename
        
        return wrapped
    
    return decorator

def register_action_permission(permission_description=None):
    """
    注册 action 对应的权限
    用法：
    @register_action_permission("Can reset user password")
    @action(methods=['POST'], detail=True)
    def reset_password(self, request, pk=None):
        ...
    """
    def decorator(func):
        # 获取视图集对应的模型
        def get_model():
            # 从函数定义的类中获取模型
            view_class = func.__qualname__.split('.')[0]
            model = None
            
            # 遍历所有已安装的应用查找模型
            for app_config in apps.get_app_configs():
                for model_class in app_config.get_models():
                    view_set_class = f"{model_class.__name__}ViewSet"
                    if view_set_class == view_class:
                        model = model_class
                        break
                if model:
                    break
            
            return model
        
        # 在装饰器应用时注册权限
        model = get_model()
        if model:
            model_name = model._meta.model_name
            action_name = func.__name__
            codename, name = generate_action_permission(
                model_name,
                action_name,
                permission_description
            )
            register_custom_permissions(model, [(codename, name)])
            
            # 保存权限信息供后续使用
            func.permission_codename = f"{model._meta.app_label}.{codename}"
        
        return func
    
    return decorator
